﻿package scrn;


import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;

import mess.*;
import media.*;
import cont.*;
import core.*;


// ================================================= Отображение перс. контактов
public class One implements Win {

// ================================================================== Переменные

//-------------------- Экран
private int dispWold; // Ширина экрана
private int dispHold; // Высота экрана

//------------------- Заголовок
//Общий фон
private int titBgX; // Координата X cтроки заголовка
private int titBgY; // Координата Y cтроки заголовка
private int titBgW; // Ширина cтроки заголовка
private int titBgH; // Высота cтроки заголовка

//Текст
private int titTextX; // Координата X заголовка
private int titTextY; // Координата Y заголовка
private int titTextW; // Ширина заголовка
private int titTextH; // Высота заголовка
private int titTextBase; // Позиция Y текста заголовка

//Значок новых сообщений
private int newX; // Координата X поля новых сообщений
private int newY; // Координата Y поля новых сообщений
private int newW; // Ширина поля новых сообщений
private int newH; // Высота поля новых сообщений

//------------------- Строка статуса
//Общий фон
private int statBgX; // Координата X cтроки статуса
private int statBgY; // Координата Y cтроки статуса
private int statBgW; // Ширина cтроки статуса
private int statBgH; // Высота cтроки статуса
//Текст
private int statTextX; // Координата X текста cтроки статуса
private int statTextY; // Координата Y текста cтроки статуса
private int statTextW; // Ширина текста статуса
private int statTextH; // Высота текста статуса
private int statTextBase; // Позиция Y текста статуса

//Поле часов
private int clkX; // Координата X поля часов
private int clkY; // Координата Y поля часов
private int clkW; // Ширина поля часов
private int clkH; // Высота поля часов
private int clkBase; // Позиция Y текста часов

//------------------- Окно сообщений
private int messX; // Координата X окна сообщений
private int messY; // Координата Y окна сообщений
private int messW; // Ширина окна сообщений
private int messH; // Высота окна сообщений
//Текст сообщений
private int textX; // Координата X окна текста сообщений
private int textY; // Координата Y окна текста сообщений
private int textW; // Ширина окна текста сообщений
private int textH; // Высота окна текста сообщений
private int textYMax; // Координата Y окна текста сообщений

// Перерисовка
private BufferedImage bg; // Картинка фона
private OneCol col; // Цветовая схема

// Разное
private ContOne one; // Текущий контакт, отображаемый экраном
private int tickCount = 0; // Счетчик тиков


// ============================================================ Изменился статус
public boolean chStat(String statText) {

	synchronized (Man.main) {
		this.drawStat();
		this.drawTit();
	}
	return true;
}


// =============================================================== Инициализация
protected One() {

}


public void fOnline(boolean fOnline) {

}


//=========================================== Освободить ресурсы и закрыть окно
public void close(int from) {

}


//============================================================== Отрисовать фон
//Полностью
private void drawBg() {

	Draw.g.setClip(0, 0, Draw.dispW, Draw.dispH);
	Draw.g.drawImage(bg, 0, 0, null);
}


//============================================================= Отрисовать часы
//Полностью
private void drawClk() {

	Draw.g.setClip(clkX, clkY, clkW, clkH);
	Draw.g.drawImage(bg, clkX, clkY, clkX + clkW, clkY + clkH, clkX, clkY, clkX
			+ clkW, clkY + clkH, null);
	drawClkText();
}


//Только текст
private void drawClkText() {

	Draw.g.setClip(clkX, clkY, clkW, clkH);
	Draw.g.setFont(Draw.fontStat);
	Draw.drawShadText(core.Clock.getTime(Setting.fClkSec), clkX, clkBase,
			col.clk, col.statShad);
}


//=========================================================== Отрисовать статус
//Полностью
private void drawStat() {

	Draw.g.setClip(statTextX, statTextY, statTextW, statTextH);
	Draw.g.drawImage(bg, statTextX, statTextY, statTextX + statTextW, statTextY
			+ statTextH, statTextX, statTextY, statTextX + statTextW, statTextY
			+ statTextH, null);
	drawStatText();
}


//Только текст
private void drawStatText() {

	Draw.g.setClip(statTextX, statTextY, statTextW, statTextH);

	Draw.g.setFont(Draw.fontStat);
	Draw.drawShadText(Man.ioMan.status, statTextX, statTextBase, col.stat,
			col.statShad);

}


//======================================================== Отрисовать заголовок
private void drawTit() {

	// Mess.m("Room.drawTitle", "Рисую заголовок");
	Draw.g.setClip(titTextX, titTextY, titTextW, titTextH);
	Draw.g.drawImage(bg, titTextX, titTextY, titTextX + titTextW, titTextY
			+ titTextH, titTextX, titTextY, titTextX + titTextW, titTextY + titTextH,
			null);
	drawTitText();
}


private void drawTitText() {

	Draw.g.setClip(titTextX, titTextY, titTextW, titTextH);
	Color color;
	if (one.info.statNum >= StatOne.ONLINE) {
		color = col.tit_online;
	} else {
		color = col.tit_offline;
	}
	Draw.g.setFont(Draw.fontTit);
	Draw.drawShadText(one.name, titTextX, titTextY + titTextBase, color,
			col.titShad);
}


//============================================ Отрисовать значок новых сообщений
private void drawNew() {

	//	Mess.m("Room.drawNew", "Рисую значок новых сообщений");
	Draw.g.setClip(newX, newY, newW, newH);
	Draw.g.drawImage(bg, newX, newY, newX + newW, newY + newH, newX, newY, newX
			+ newW, newY + newH, null);

	if (Man.contMan.getNewState() > 0) { // Есть новые
		Draw.g.setColor(col.titShad);
		Draw.g.fillRect(newX + Draw.fact, newY + newH - Draw.fact, newW, Draw.fact);
		Draw.g.fillRect(newX + newW - Draw.fact, newY + Draw.fact, Draw.fact, newH
				- Draw.fact);

		Draw.rectG(Draw.g, newX + 1, newY + 1, newW - Draw.fact - 2, newH
				- Draw.fact - 2, col.newBg1, col.newBg2);
		Draw.g.setColor(col.lineNew);
		Draw.g.drawLine(newX, newY, newX + newW - Draw.fact - 1, newY + newH
				- Draw.fact - 1);
		Draw.g.drawLine(newX + newW - Draw.fact - 1, newY, newX, newY + newH
				- Draw.fact - 1);
		Draw.g.drawLine(newX, newY, newX + newW - Draw.fact - 1, newY);
		Draw.g.drawLine(newX, newY + newH - Draw.fact - 1, newX + newW - Draw.fact
				- 1, newY + newH - Draw.fact - 1);
		Draw.g.drawLine(newX, newY, newX, newY + newH - Draw.fact - 1);
		Draw.g.drawLine(newX + newW - Draw.fact - 1, newY, newX + newW - Draw.fact
				- 1, newY + newH - Draw.fact - 1);
	}
}


// =================================================================== Сообщения

//Все
private void drawMess() {

	drawMessBg();
	drawMessText();
}


//Фон
private void drawMessBg() {

	// Mess.m("Room.drawMessBg", "Рисую фон сообщений");
	Draw.g.setClip(messX, messY, messW, messH);
	Draw.g.drawImage(bg, messX, messY, messX + messW, messY + messH, messX,
			messY, messX + messW, messY + messH, null);
}


//Текст
private void drawMessText() {

	// Mess.m("one.drawMessText", "Рисую текст сообщений");

	int blkType; // Тип отрисовываемого блока
	int bP; // Указатель на начало текста в блоке
	int eP; // Указатель на конец текста в блоке
	boolean fSel; // Отрисовывается выделенное сообщение
	int parseP; // Указатель на символ строки парсинга, который необходимо читать
	int rowH; // Высота строки
	int rowEnd; // Первый символ следующей строки
	int rowLen; // Длина строки в байтах
	int scrX; // Позиция X отрисовки на экране
	String time; // Время в сообщении
	int width; // Ширина блока в точках
	MessOne mess = null; // Отрисовываемое сообщение


	try {
		// int messNum = 0; // Номер отрисовываемого сообщения
		mess = one.getFirst(); // Первое отрисовываемое сообщение
		int scrY = textY + one.getDisplace(); // Позиция Y отрисовки на экране
		// Mess.m("one.drawMessText", "displace=" + cont.getDisplace());

		textYMax = textY + textH;

		Draw.g.setClip(textX, textY, textW, textH + 1);
		Man.picAni.reset(col.messBgSel, textX, textY, textW, textH + 1, bg);

		Draw.g.setFont(Draw.fontMess);

		// Цикл отрисовки сообщений
		while ((mess != null) && scrY < textYMax) {


			parseP = 0; // Указатель на символ строки парсинга, который необходимо читать
			String text = mess.text;
			char[] textCh = text.toCharArray();
			//			Mess.m("one.drawMessText", "Рисую: " + mess);

			fSel = one.isSel();
			if (fSel) { // Отрисовываем выделенное

				Draw.g.setClip(messX, messY, messW, messH + 1);

				Draw.g.setColor(col.messBgSel);
				Draw.g.fillRect(messX, scrY + 1, messW, mess.hTot - 1);

				// Линии
				Draw.g.setColor(col.lineSel);
				Draw.g.drawLine(messX, scrY, messX + messW, scrY);
				Draw.g.drawLine(messX, scrY + mess.hTot, messX + messW, scrY
						+ mess.hTot);

				Draw.g.setClip(textX, textY, textW, textH + 1);
			}

			do {
				scrX = textX;

				rowLen = mess.res[parseP];
				rowEnd = parseP + rowLen;
				parseP++;
				rowH = mess.res[parseP++];
				scrY += rowH;

				do { // Цикл отрисовки блоков одной строки
					blkType = mess.res[parseP++];
					switch (blkType) {

					case Message.B_TEXT:
						Draw.g.setColor(col.mess[mess.color]);
						bP = mess.res[parseP++];
						eP = mess.res[parseP++];
						width = mess.res[parseP++];
						Draw.g.drawChars(textCh, bP, eP - bP + 1, scrX, scrY
								- Draw.fontMessDes);
						scrX += width;
						break;

					case Message.B_SMILE:
						int smlNum = mess.res[parseP++];
						Pic sml = (Pic) Man.resMan.getRes(new Long(smlNum));
						int smlY = scrY - sml.h;
						if (sml.type == Resource.RES_SML_ANI) { // Смайл анимирован
							if ((scrY < Draw.dispH) && (smlY > 0)) { // Умещается на экране
								Man.picAni.addPic(sml, scrX, smlY, fSel);
							}
						}
						sml.draw(Draw.g, scrX, smlY);
						scrX += sml.w;
						break;

					case Message.B_TIME:
						time = mess.getTimeString();
						Draw.g.setFont(Draw.fontClk);
						Draw.g.setColor(col.messClk[mess.color]);
						Draw.g.drawString(time, scrX, scrY - Draw.fontMessDes);
						scrX += Draw.timeMessW + Draw.timeMessOff;
						Draw.g.setFont(Draw.fontMess);
						break;

					case Message.B_TAB:
						break;

					default:
						Mess.err("one.drawMessText", "Неизвестный тип блока (" + blkType
								+ ")");
					}
				} while (parseP < rowEnd);

				parseP++;
			} while ((scrY < textYMax) && (parseP < mess.res.length));

			mess = one.getNext(); // Конец цикла отрисовки блоков одного сообщения
		}
		//	}
	} catch (Exception e) {
		Mess.err("one.drawMessText", "Ошибка отрисовки сообщения: " + mess, e);
	}
	// Mess.m("one.drawMessText", "Конец отрисовки текста");
}


// ============================================= Извещение о пришедшем сообщении
public boolean inText(int contType, int contNum, Message message) {

	switch (contType) {

	case Cont.ONE:
		if (Man.contMan.isSel(Cont.ONE, contNum)) {
			synchronized (Man.main) {
				drawMess();
			}
		} else {
			synchronized (Man.main) {
				drawNew();
			}
		}
		break;

	case Cont.ROOM:
		synchronized (Man.main) {
			drawNew();
		}
		break;

	default:
		Mess.m("Win.inText", "Неизвестный тип контакта: " + contType);
	}

	return true;
}


// ===================================================== Графическое/стандартное
public boolean isGraphic() {

	return true;
}


//=============================================== Обработчик событий клавиатуры
public boolean keyPressed(int action) {

	boolean fFlush = false;

	switch (action) {
	case KeyEvent.VK_UP:
		synchronized (Man.main) {
			one.selUp();
			drawMess();
		}
		fFlush = true;
		break;

	case KeyEvent.VK_DOWN:
		synchronized (Man.main) {
			one.selDown();
			drawMess();
		}
		fFlush = true;
		break;

	case KeyEvent.VK_LEFT:
		Man.scrMan.showPrevCont();
		break;

	case KeyEvent.VK_RIGHT:
		Man.scrMan.showNextCont();
		break;
	//	
	//			case ScrMan.FIRE:
	//				Man.scrMan.sendMess();
	//				break;
	//	
	//			case ScrMan.GAME_A:
	//				Man.scrMan.showContList();
	//				break;
	//	
	//			case ScrMan.GAME_B:
	//				Man.scrMan.outRoomWho();
	//				break;
	//	
	//			case ScrMan.GAME_C:
	//				break;
	//	
	//			case ScrMan.GAME_D:
	//				Man.scrMan.sendMess();
	//				break;
	}

	return fFlush;

}


//=================================================== Создать всю картинку фона
private void makeAllBg() {

	// Mess.m("Room.makeAllBg", "Создаю картинки фона");
	try {

		if ((bg == null) || (bg.getWidth() != Draw.dispW)
				|| (bg.getHeight() != Draw.dispH)) {

			bg = new BufferedImage(Draw.dispW, Draw.dispH,
					BufferedImage.TYPE_INT_ARGB);
			Graphics g = bg.getGraphics();

			g.setClip(0, 0, Draw.dispW, Draw.dispH);

			makeScrBg(g);
			makeTitBg(g);
			makeStatBg(g);

		}
	} catch (Exception e) {
		Mess.err("Room.makeAllBg", "Не могу создать картинку фона", e);
	}
}


// ========================================================== Создать фон экрана
private void makeScrBg(Graphics g) {

	Draw.rectG(g, 0, 0, Draw.dispW, Draw.dispH >> 2, col.scrBg1, col.scrBg2);
	Draw.rectG(g, 0, Draw.dispH >> 2, Draw.dispW, Draw.dispH - (Draw.dispH >> 2),
			col.scrBg2, col.scrBg1);
}


//========================================================= Создать фон статуса
private void makeStatBg(Graphics g) {

	Draw.rectG(g, statBgX, statBgY + Draw.fact, statBgW, (statBgH - Draw.fact2)
			- ((statBgH - Draw.fact2) >> 2), col.statBg1, col.statBg2);
	Draw.rectG(g, statBgX, statBgY + Draw.fact + (statBgH - Draw.fact2)
			- ((statBgH - Draw.fact2) >> 2), statBgW, (statBgH - Draw.fact2) >> 2,
			col.statBg2, col.statBg1);
	g.setColor(col.line);
	g.fillRect(statBgX, statBgY, statBgW, Draw.fact);
	g.fillRect(statBgX, statBgY + statBgH - Draw.fact, statBgW, Draw.fact);
}


//======================================================= Создать фон заголовка
private void makeTitBg(Graphics g) {

	Draw.rectG(g, titBgX, titBgY + Draw.fact, titBgW, (titBgH - Draw.fact2)
			- ((titBgH - Draw.fact2) >> 2), col.titBg1, col.titBg2);
	Draw.rectG(g, titBgX, titBgY + Draw.fact + (titBgH - Draw.fact2)
			- ((titBgH - Draw.fact2) >> 2), titBgW, (titBgH - Draw.fact2) >> 2,
			col.titBg2, col.titBg1);
	g.setColor(col.line);
	g.fillRect(titBgX, titBgY, titBgW, Draw.fact);
	g.fillRect(titBgX, titBgY + titBgH - Draw.fact, titBgW, Draw.fact);
}


// ================================================= Задать отображаемый контакт
protected void setCont(ContOne cont, int contNum) {

	one = cont;
	col = new OneCol(); // TODO Убрать

	/*
	 * try { this.contNum = contNum; this.cont = cont; if (cont.colSch != colNum)
	 * { colNum = cont.colSch; // this.col = event.getOneCol(colNum); } titText =
	 * cont.info.login; } catch (Exception e) { Mess.err("One.setCont",
	 * "Подготовить экран для отображения не удалось", e); }
	 */
}


// ============================================================= Отрисовать окно
public void show(Win oldWin) {

	synchronized (Man.main) {
		if ((dispWold != Draw.dispW) || (dispHold != Draw.dispH)) { // Размер экрана
			// изменился
			updSize();
			makeAllBg();
		}

		drawBg();
		drawTitText();
		drawNew();

		drawStatText();
		drawClkText();
		one.setSize(textW, textH);
		drawMessText();
	}

}


// ====================================================== Тик системного таймера 
public boolean tick() {

	boolean fFlush;

	tickCount += Setting.tickSpeed;

	fFlush = Man.picAni.drawAll();

	if (tickCount >= 1000) {
		// TODO Раз в секунду или в 20 секунд - в зависимости от настройки часов
		tickCount -= 1000;
		synchronized (Man.main) {
			drawClk();
		}
		fFlush = true;
	}

	return fFlush;
}


//========================================================= Пересчитать размеры
public void updSize() {

	// Заголовок
	titBgX = Draw.fact;
	titBgY = 0;
	titBgW = Draw.dispW - Draw.fact2;
	titBgH = Draw.fontTitH + Draw.fact4;

	// Значок наличия новых сообщений
	newH = titBgH >> 1;
	newW = newH + (newH >> 1);
	newX = titBgX + titBgW - Draw.fact - newW;
	newY = (titBgY + (titBgH >> 1)) - (newH >> 1);

	// Текст заголовка
	titTextX = titBgX + Draw.fact;
	titTextY = titBgY + Draw.fact;
	titTextW = titBgW - newW - Draw.fact3;
	titTextH = Draw.fontTitH + Draw.fact2;

	titTextBase = titTextY + Draw.fontTitH + Draw.fact - Draw.fontTitDes
			- Draw.fontTitDes;

	// Фон статуса
	statBgX = Draw.fact;
	statBgH = Draw.fontStatH + Draw.fact4;
	statBgY = Draw.dispH - statBgH;
	statBgW = Draw.dispW - Draw.fact2;

	// Часы
	clkW = Draw.timeStatW + Draw.fact;
	clkH = Draw.fontStatH + Draw.fact;
	clkX = statBgX + statBgW - clkW;
	clkY = statBgY + Draw.fact2; /**/

	// Текст статуса
	statTextX = statBgX + Draw.fact2;
	statTextY = statBgY + Draw.fact;
	statTextW = statBgW - clkW - Draw.fact5;
	statTextH = Draw.fontStatH + Draw.fact2; /**/
	statTextBase = statTextY + Draw.fact + Draw.fontStatH - Draw.fontStatDes;
	clkBase = statTextBase;

	// Окно сообщений
	messX = Draw.fact;
	messY = titBgY + titBgH + Draw.fact;
	messW = Draw.dispW - Draw.fact2;
	messH = statBgY - messY - Draw.fact;

	// Текст сообщений
	textX = messX + Draw.fact;
	textY = messY;
	textW = messW - Draw.fact2;
	textH = messH - Draw.fact;
	textYMax = textY + textH;

}


}
